/**
 * 通过上一章节，我们明白了什么是依赖？何时收集依赖？
 * 以及收集的依赖存放到何处？那么我们收集的依赖到底是谁？
 * 
 * 虽然我们一直在说”谁用到了这个数据谁就是依赖“，但是这仅仅是在口语层面上，
 * 那么反应在代码上该如何来描述这个”谁“呢？
 * 
 * 其实在Vue中还实现了一个叫做Watcher的类，而Watcher类的实例就是我们上面所说的那个"谁"。
 * 换句话说就是：谁用到了数据，谁就是依赖，我们就为谁创建一个Watcher实例。
 * 在之后数据变化时，我们不直接去通知依赖更新，而是通知依赖对应的Watch实例，由Watcher实例去通知真正的视图。
 * Watcher类的具体实现如下：
*/

class Watcher{
    constructor(vm, expOrFn, cd){
        this.vm = vm
        this.cb = cb
        this.getter = parsePath(expOrFn)
        this.value = this.get()
    }

    get () {
        window.target = this
        const vm = this.vm
        let value = this.getter.call(vm, vm)
        window.target = undefined
        return value
    }

    update () {
        const oldValue = this.value
        this.value = this.get()
        this.cb.call(this.vm, this.value, oldValue)
    }
}

/**
 * Parse simple path.
 * 把一个形如'data.a.b.c'的字符串路径所表示的值，从真实的data对象中取出来
 * 例如：
 * data = {a:{b:{c:2}}}
 * parsePath('a.b.c')(data)  // 2
*/
const bailRE = /[^\w.$]/
export default function parsePath (path) {
    if(bailRE.test(path)){
        return
    }
    const segments = path.split('.')
    return function (obj) {
        for (let i = 0; i < segments.length; i++) {
            if (!obj){ return }
            obj = obj[segments[i]]
        }
        return
    }
}